from rest_framework.exceptions import ValidationError
from rest_framework.serializers import ModelSerializer
from rest_framework import serializers
from erp_system.models import UserModel
import re

from erp_system.serializer.dept_serializer import DeptSerializer
from erp_system.serializer.role_serializer import BaseRolesSerializer


class UserRegisterSerializer(ModelSerializer):
    """
        用户注册的序列化类
    """

    class Meta:
        model = UserModel
        fields = ('id', 'username', 'password', 'phone', 'real_name')
        extra_kwargs = {
            'username': {
                'min_length': 2,
                'max_length': 12
            },
            'password': {
                'min_length': 6,
                'max_length': 8,
                # write_only这里意思是在写的时候是明文，读取的时候是密文
                'write_only': True
            }
        }

    def validate_phone(self, phone):
        """
        验证手机号，自定义一个验证的函数（命名规则：validate_+字段名字）
        """
        if not phone:
            return phone
        else:
            if not re.match(r'^1[345689]\d{9}$', phone):
                raise ValidationError('请输入正确的手机号')
        return phone

    def create(self, validated_data):
        """必须重写create函数，因为用户密码是不能直接插入数据库的"""
        user = UserModel.objects.create_user(**validated_data)
        return user


class UserUpdateOrDeleteSerializer(ModelSerializer):
    """
        只用于：修改和删除。
            修改包括：id，phone，real_name，role_id，dept_id。
            删除只是用户id。
    """

    class Meta:
        model = UserModel
        fields = ('id', 'phone', 'real_name', 'roles', 'dept')


class UserGetSerializer(ModelSerializer):
    """
        用于查询用户，
            返回：id，username，real_name，phone，所有角色的详细信息，用户所在部门的详细信息，
    """

    # 一个用户可以拥有多个角色，但只能所属一个部门。
    roles = BaseRolesSerializer(many=True, read_only=True)
    dept = DeptSerializer(many=False, read_only=True)

    class Meta:
        model = UserModel
        fields = ('id', 'username', 'phone', 'real_name', 'roles', 'dept')


class ResetPasswordSerializer(ModelSerializer):
    """
        只用于：
            修改密碼，包含三个参数：原始密码，新密码，新密码确认
    """
    new_password = serializers.CharField(required=True, write_only=True)
    confirm_password = serializers.CharField(required=True, write_only=True)

    class Meta:
        model = UserModel
        fields = ('id', 'password', 'new_password', 'confirm_password')   # 都是只用于反序列化
        extra_kwargs = {
            'passsword': {'write_only': True},
            'new_passsword': {'write_only': True},
            'confirm_password': {'write_only': True}
        }

    def validate(self, attrs):
        """
            表单参数的验证
        """
        password = attrs.get('password')
        new_password = attrs.get('new_password')
        confirm_password = attrs.get('confirm_password')
        if not password:
            raise ValidationError('字段password为必填项')
        if not new_password:
            raise ValidationError('字段new_password为必填项')
        if not confirm_password:
            raise ValidationError('字段confirm_password为必填项')
        if confirm_password != new_password:
            raise ValidationError('两次密码不一致')
        return attrs

    def save(self, **kwargs):
        # 必须重写save函数，否则明文的密码会保存到数据库中
        if not self.instance.check_password(self.validated_data.get('password')):
            raise ValidationError('原始密码错误，请重新输入原始密码')
        self.instance.set_password(self.validated_data.get('new_password'))
        self.instance.save()
        return self.instance


class AxiosTestSerializer(ModelSerializer):
    """
        测试axios
    """

    class Meta:
        model = UserModel
